package org.beetl.json;

import java.io.IOException;
import java.io.Writer;
import java.util.LinkedList;

import org.beetl.json.util.ContextLocal;
import org.beetl.json.util.IntIOWriter;

public class JsonWriter {
	Writer w = null ;
	char quotes = 0;
	boolean pretty = false ;
	int indent = 0;
	LinkedList<Object> path = new LinkedList<Object>();
	ContextLocal localBuffer = ContextLocal.get();
	public JsonWriter(Writer w){
		this.w = w;
		if(JsonTool.UseSingleQuotes){
			quotes = '\'';
		}else{
			quotes= '\"';
		}
		pretty = JsonTool.pretty;
		
	}
	
	
	
	public void writeComma() throws IOException{
		w.write(',');
	
	}
	
	public void writeScopeChar(char c) throws IOException{
		
		if(pretty){			
			switch(c){
			case '{':
			case '[':
				w.write('\n');
				this.writeIndent();				
				this.indent++;
				break;
			case '}':
			case ']':
				w.write('\n');
				this.indent--;
				writeIndent();				
				break;			
			}
			
			
		}
		
		
		w.write(c);
	}
	public void  write(char c) throws IOException{
		
		
		w.write(c);
	}
	

	public void writeKey(String key)throws IOException{
		
		if(this.pretty){
			w.write('\n');
			writeIndent();
		}
		w.write(quotes);
		w.write(key);
		w.write(quotes);
	}
	
	public void writeChars(char[] cs)throws IOException{
		w.write(cs);
	}
	

	public void write(Object  o) throws IOException{
		if(o==null){
			w.write("null");
		}else{
			if(o instanceof Boolean){
				w.write(o.toString());
			}else if(o instanceof Number){
				
				if(o instanceof Integer){
					IntIOWriter.writeInteger(this, (Integer)o);
				}else{
					w.write(o.toString());
				}
				
			}else if(o instanceof DirectOutputValue){
				w.write(o.toString());
			}else{
				w.write(quotes);
				w.write(o.toString());
				w.write(quotes);
			}
		
		}
		
	}
	
	public void writeNumberChars(char[] chars, int len) throws IOException

	{
		this.w.write(chars, 0, len);

	}
	
	protected void writeIndent() throws IOException{
		for(int i=0;i<indent;i++){
			w.write('\t');
		}
	}
	
	public void addObject(String name,Object o){
		this.path.add(o);
	}
	
	public boolean containObject(Object o){
		return path.contains(o);
	}
	
	public void removeLast(){
		path.removeLast();
	}

	public ContextLocal getLocalBuffer() {
		return localBuffer;
	}
	

	
	
	
	
}
